#!/usr/bin/env python
#
#   Copyright (C) 2006 Jonathan Saggau                                    
#   saggau@gmail.com                                                      
#                                                                         
#   This program is free software; you can redistribute it and/or modify  
#   it under the terms of the GNU General Public License as published by  
#   the Free Software Foundation; either version 2 of the License, or     
#   (at your option) any later version.                                   
#                                                                         
#   This program is distributed in the hope that it will be useful,       
#   but WITHOUT ANY WARRANTY; without even the implied warranty of        
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         
#   GNU General Public License for more details.                          
#                                                                         
#   You should have received a copy of the GNU General Public License     
#   along with this program; if not, write to the                         
#   Free Software Foundation, Inc.,                                       
#   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.  
#

"""
supercollider message building functions
"""
from scosc import tools
import types

def _flattenMsgRecurse(listCompound, listFlat):
    for entry in listCompound:
        #flatten iff it's a collection AND there's no 'b' (binary) tag
        if (isinstance(entry, types.ListType) or\
            isinstance(entry, types.TupleType)) \
            and ('b' not in entry):
                _flattenMsgRecurse(entry, listFlat)
        else:
            listFlat.append(entry)

def _flattenMsg(listCompound):
    """Turns a nested list/tuple into a 1D list. i.e. [[0,1,2,3],4,5]
    returns [0,1,2,3,4,5]"""
    listFlat = []
    _flattenMsgRecurse(listCompound, listFlat)
    try:
        listFlat.remove(None)
    except ValueError:
        pass
    return(listFlat)

def msg(*args, **kwargs):
    msg = _flattenMsg(args)
    try:
        completionmsg = kwargs['completionmsg']
        if completionmsg:
            binary = _binarymsg(completionmsg)
            msg.append([binary, 'b'])
            # the [msg, 'b'] tells the message builder to
            # treat the data as binary
    except KeyError: #no completionmsg kwarg
        pass
    return msg

def _binarymsg(msglist):
    binary = tools.OSCMessage()
    for each in msglist:
        binary.append(each)
    return binary.getBinary()
    
def dictmsg(cmdString, argsDict, completionmsg = None):
    """builds a msg with a key:value args dict"""
    args = []
    for key in argsDict.keys():
        args.extend([key, argsDict[key]])
    # in case there is a list or tuple in the argsDict
    return msg(cmdString, args, completionmsg = completionmsg)
    
def setnmsg(msghead, id, indexValuesDict):
    args = [id]
    for index in indexValuesDict.keys():
        values = indexValuesDict[index]
        args.extend([index, len(values), values])
    return msg(msghead, args)